﻿using ChineseChess.Game;
using ChineseChess.Game.AI;
using ChineseChess.Game.Pieces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents; 
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace ChineseChess
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Chessboard.CurrectCamp = true;
            init();
            initPieces();
        }

        /// <summary>
        /// 初始化棋子
        /// </summary>
        private void initPieces()
        {
            Chessboard.PieceList.Clear();

            #region  黑方棋子
            JuPiece ju20 = new JuPiece(2,vgap, hgap);
            ju20.setXy(0,0); 
            chessboard.Children.Add(ju20);
            Chessboard.PieceList.Add(ju20);

            MaPiece ma20 = new MaPiece(2, vgap, hgap);
            ma20.setXy(1, 0); 
            chessboard.Children.Add(ma20);
            Chessboard.PieceList.Add(ma20);

            XiangPiece xiang20 = new XiangPiece(2, vgap, hgap);
            xiang20.setXy(2, 0);
            chessboard.Children.Add(xiang20);
            Chessboard.PieceList.Add(xiang20);

            ShiPiece shi20 = new ShiPiece(2, vgap, hgap);
            shi20.setXy(3, 0);
            chessboard.Children.Add(shi20);
            Chessboard.PieceList.Add(shi20);

            JiangPiece jiang2 = new JiangPiece(2, vgap, hgap);
            jiang2.setXy(4, 0);
            chessboard.Children.Add(jiang2);
            Chessboard.PieceList.Add(jiang2);

            ShiPiece shi21 = new ShiPiece(2, vgap, hgap);
            shi21.setXy(5, 0);
            chessboard.Children.Add(shi21);
            Chessboard.PieceList.Add(shi21);

            XiangPiece xiang21 = new XiangPiece(2, vgap, hgap);
            xiang21.setXy(6, 0);
            chessboard.Children.Add(xiang21);
            Chessboard.PieceList.Add(xiang21);

            MaPiece ma21 = new MaPiece(2, vgap, hgap);
            ma21.setXy(7, 0);
            chessboard.Children.Add(ma21);
            Chessboard.PieceList.Add(ma21);

            JuPiece ju21 = new JuPiece(2, vgap, hgap);
            ju21.setXy(8, 0);
            chessboard.Children.Add(ju21);
            Chessboard.PieceList.Add(ju21);

            PaoPiece pao20 = new PaoPiece(2, vgap, hgap);
            pao20.setXy(1, 2);
            chessboard.Children.Add(pao20);
            Chessboard.PieceList.Add(pao20);

            PaoPiece pao21 = new PaoPiece(2, vgap, hgap);
            pao21.setXy(7, 2);
            chessboard.Children.Add(pao21);
            Chessboard.PieceList.Add(pao21);

            BingPiece bing20 = new BingPiece(2, vgap, hgap);
            bing20.setXy(0, 3);
            chessboard.Children.Add(bing20);
            Chessboard.PieceList.Add(bing20);

            BingPiece bing21 = new BingPiece(2, vgap, hgap);
            bing21.setXy(2, 3);
            chessboard.Children.Add(bing21);
            Chessboard.PieceList.Add(bing21);

            BingPiece bing22 = new BingPiece(2, vgap, hgap);
            bing22.setXy(4, 3);
            chessboard.Children.Add(bing22);
            Chessboard.PieceList.Add(bing22);

            BingPiece bing23 = new BingPiece(2, vgap, hgap);
            bing23.setXy(6, 3);
            chessboard.Children.Add(bing23);
            Chessboard.PieceList.Add(bing23);

            BingPiece bing24 = new BingPiece(2, vgap, hgap);
            bing24.setXy(8, 3);
            chessboard.Children.Add(bing24);
            Chessboard.PieceList.Add(bing24);

            #endregion

            #region  红方棋子
            JuPiece ju10 = new JuPiece(1, vgap, hgap);
            ju10.setXy(0, 9);
            chessboard.Children.Add(ju10);
            Chessboard.PieceList.Add(ju10);

            MaPiece ma10 = new MaPiece(1, vgap, hgap);
            ma10.setXy(1, 9);
            chessboard.Children.Add(ma10);
            Chessboard.PieceList.Add(ma10);

            XiangPiece xiang10 = new XiangPiece(1, vgap, hgap);
            xiang10.setXy(2, 9);
            chessboard.Children.Add(xiang10);
            Chessboard.PieceList.Add(xiang10);

            ShiPiece shi10 = new ShiPiece(1, vgap, hgap);
            shi10.setXy(3, 9);
            chessboard.Children.Add(shi10);
            Chessboard.PieceList.Add(shi10);

            JiangPiece jiang1 = new JiangPiece(1, vgap, hgap);
            jiang1.setXy(4, 9);
            chessboard.Children.Add(jiang1);
            Chessboard.PieceList.Add(jiang1);

            ShiPiece shi11 = new ShiPiece(1, vgap, hgap);
            shi11.setXy(5, 9);
            chessboard.Children.Add(shi11);
            Chessboard.PieceList.Add(shi11);

            XiangPiece xiang11 = new XiangPiece(1, vgap, hgap);
            xiang11.setXy(6, 9);
            chessboard.Children.Add(xiang11);
            Chessboard.PieceList.Add(xiang11);

            MaPiece ma11 = new MaPiece(1, vgap, hgap);
            ma11.setXy(7, 9);
            chessboard.Children.Add(ma11);
            Chessboard.PieceList.Add(ma11);

            JuPiece ju11 = new JuPiece(1, vgap, hgap);
            ju11.setXy(8, 9);
            chessboard.Children.Add(ju11);
            Chessboard.PieceList.Add(ju11);

            PaoPiece pao10 = new PaoPiece(1, vgap, hgap);
            pao10.setXy(1, 7);
            chessboard.Children.Add(pao10);
            Chessboard.PieceList.Add(pao10);

            PaoPiece pao11 = new PaoPiece(1, vgap, hgap);
            pao11.setXy(7, 7);
            chessboard.Children.Add(pao11);
            Chessboard.PieceList.Add(pao11);

            BingPiece bing10 = new BingPiece(1, vgap, hgap);
            bing10.setXy(0, 6);
            chessboard.Children.Add(bing10);
            Chessboard.PieceList.Add(bing10);

            BingPiece bing11 = new BingPiece(1, vgap, hgap);
            bing11.setXy(2, 6);
            chessboard.Children.Add(bing11);
            Chessboard.PieceList.Add(bing11);

            BingPiece bing12 = new BingPiece(1, vgap, hgap);
            bing12.setXy(4, 6);
            chessboard.Children.Add(bing12);
            Chessboard.PieceList.Add(bing12);

            BingPiece bing13 = new BingPiece(1, vgap, hgap);
            bing13.setXy(6, 6);
            chessboard.Children.Add(bing13);
            Chessboard.PieceList.Add(bing13);

            BingPiece bing14 = new BingPiece(1, vgap, hgap);
            bing14.setXy(8, 6);
            chessboard.Children.Add(bing14);
            Chessboard.PieceList.Add(bing14);

            #endregion
        }

        private int hgap;
        private int vgap;
        /// <summary>
        /// 初始化棋盘
        /// </summary>
        private void init()
        {
            #region 参数初始化
            chessboard.Children.Clear();//清空棋盘
            int width = (int)chessboard.ActualWidth; //棋盘宽度
            int height = (int)chessboard.ActualHeight; //棋盘高度
            int hlinenum = 10; //横向线数
            int vlinenum = 9; //纵向线数
            int i = 0;

            hgap = height / (hlinenum-1); //横向间隔
            vgap = width / (vlinenum-1); //纵向间隔
            int gap = 2; //棋盘向下偏移量
            #endregion

            #region 绘制横向线
            for (i = 0; i < hlinenum; i++)
            {
                Line line = new Line();
                line.X1 = 0;
                line.Y1 = (hgap * i)+ gap;
                line.X2 = width;
                line.Y2 = (hgap * i)+ gap;
                line.StrokeThickness = 1;
                line.Stroke = new SolidColorBrush(Colors.Black);

                chessboard.Children.Add(line);
            }
            #endregion

            #region 绘制纵向线
            for (i = 0; i < vlinenum; i++)
            {
                Line line1 = new Line();
                line1.X1 = (vgap * i);
                line1.Y1 = 0 + gap;
                line1.X2 = (vgap * i); 
                line1.Y2 = (hgap * 4) + gap;
                line1.StrokeThickness = 1;
                line1.Stroke = new SolidColorBrush(Colors.Black);

                Line line2 = new Line();
                line2.X1 = (vgap * i);
                line2.Y1 = (hgap * 5) + gap;
                line2.X2 = (vgap * i); 
                line2.Y2 = (hgap * 9) + gap;
                line2.StrokeThickness = 1;
                line2.Stroke = new SolidColorBrush(Colors.Black);

                chessboard.Children.Add(line1);
                chessboard.Children.Add(line2);
            }
            #endregion

            #region 画皇宫斜线
            Line line3 = new Line();
            line3.X1 = (vgap * 3);
            line3.Y1 = 0 + gap;
            line3.X2 = (vgap * 5);
            line3.Y2 = (hgap * 2) + gap;
            line3.StrokeThickness = 1;
            line3.Stroke = new SolidColorBrush(Colors.Black);
            chessboard.Children.Add(line3);

            Line line4 = new Line();
            line4.X1 = (vgap * 5);
            line4.Y1 = 0 + gap;
            line4.X2 = (vgap * 3);
            line4.Y2 = (hgap * 2) + gap;
            line4.StrokeThickness = 1;
            line4.Stroke = new SolidColorBrush(Colors.Black);
            chessboard.Children.Add(line4);

            Line line5 = new Line();
            line5.X1 = (vgap * 3);
            line5.Y1 = (hgap * 7) + gap;
            line5.X2 = (vgap * 5);
            line5.Y2 = (hgap * 9) + gap;
            line5.StrokeThickness = 1;
            line5.Stroke = new SolidColorBrush(Colors.Black);
            chessboard.Children.Add(line5);

            Line line6 = new Line();
            line6.X1 = (vgap * 5);
            line6.Y1 = (hgap * 7) + gap;
            line6.X2 = (vgap * 3);
            line6.Y2 = (hgap * 9) + gap;
            line6.StrokeThickness = 1;
            line6.Stroke = new SolidColorBrush(Colors.Black);
            chessboard.Children.Add(line6);
            #endregion

        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            init();
            initPieces();
        }

        /// <summary>
        /// 是否选中棋子
        /// </summary>
        private bool isSelect = false;
        private Piece SelectPiece = null;

        /// <summary>
        /// 检查游戏是否结束，0未结束，1红胜，2黑胜
        /// </summary>
        /// <param name="pies"></param>
        /// <returns></returns>
        private int checkIsFail(List<Piece> pies)
        {
            bool redKing = false;
            bool blackKing = false;
            for (int i = 0; i < pies.Count; i++)
            {
                Piece pie = pies[i];
                if(pie.Name == ChessName.将 )
                {
                    if(pie.isRed)
                    {
                        redKing = true;
                    }
                    else
                    {
                        blackKing = true;
                    }
                }
            }

            if (redKing && blackKing)
            {
                return 0;
            }
            if(blackKing == false)
            {
                return 1;
            }
            if(redKing == false)
            {
                return 2;
            }
            return 0;
        }

        private void chessboard_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
             
            int x = (int)e.GetPosition(chessboard).X;
            int y = (int)e.GetPosition(chessboard).Y;

            if (isSelect)
            {
                int xz = (x + vgap/2) / vgap;
                int yz = (y + hgap/2) / hgap;

                for (int i = 0; i < chessboard.Children.Count; i++)
                {
                    var pie = chessboard.Children[i];
                    if (pie is Piece)
                    {
                        var piece = (Piece)(pie);
                        if (piece != SelectPiece && piece.X == xz && piece.Y == yz)
                        {   //吃子
                            List<Point> point = SelectPiece.rule.getNextPos(SelectPiece,Chessboard.PieceList); //获取下一步可以走的点

                            if (point.Contains(new Point(xz, yz)))
                            {
                                if (piece.isRed != SelectPiece.isRed) // 不是同一方的子，吃
                                { 
                                    chessboard.Children.Remove(piece);
                                    Chessboard.PieceList.Remove(piece);
                                    SelectPiece.BorderColor = SelectPiece.ColorType == Colors.Red ? Colors.Black : Colors.Red;
                                    isSelect = false;
                                    SelectPiece.X = xz;
                                    SelectPiece.Y = yz;
                                    SelectPiece.InvalidateVisual();
                                    ClearMark();
                                    if (piece.Name == ChessName.将)
                                    {
                                        MessageBox.Show((piece.isRed ? "黑方" : "红方") + "胜！");
                                        init();
                                        initPieces();
                                        return;
                                    }
                                    Chessboard.ChangeCamp();
                                    UsingAi.Run(Chessboard.PieceList, chessboard);
                                    int isover = checkIsFail(Chessboard.PieceList);
                                    if(isover != 0 )
                                    {
                                        MessageBox.Show((isover==2 ? "黑方" : "红方") + "胜！");
                                        init();
                                        initPieces();
                                        return; 
                                    }
                                    Chessboard.ChangeCamp();
                                    return;
                                }
                            }
                            else
                            {
                                //同一方的子，不走
                                return;
                            }
                        }
                    }
                }

                List<Point> points = SelectPiece.rule.getNextPos(SelectPiece,Chessboard.PieceList); //获取下一步可以走的点

                if(points.Contains(new Point(xz,yz)))
                {
                    //可以走子
                    SelectPiece.BorderColor = SelectPiece.ColorType == Colors.Red ? Colors.Black : Colors.Red;
                    isSelect = false;
                    SelectPiece.X = xz;
                    SelectPiece.Y = yz;
                    SelectPiece.InvalidateVisual();
                    ClearMark();
                    Chessboard.ChangeCamp();
                    UsingAi.Run(Chessboard.PieceList,chessboard);
                    int isover = checkIsFail(Chessboard.PieceList);
                    if (isover != 0)
                    {
                        MessageBox.Show((isover == 2 ? "黑方" : "红方") + "胜！");
                        init();
                        initPieces();
                        return;
                    }
                    Chessboard.ChangeCamp();
                    return;
                }
            }

            for (int i = 0; i < chessboard.Children.Count; i++) 
            {
                var pie = chessboard.Children[i];
                if (pie is Piece)
                {   //棋子判定
                    Piece piece = (Piece)(pie);
                    if(x< piece.getGapX()+piece.Width/2 && x > piece.getGapX() - piece.Width / 2 && y< piece.getGapY() + piece.Height / 2 && y > piece.getGapY() - piece.Height / 2)
                    {

                        //System.Windows.Forms.MessageBox.Show(piece.Name.ToString());
                        if (piece.BorderColor == Colors.Blue)
                        {
                            piece.BorderColor = piece.ColorType == Colors.Red ? Colors.Black : Colors.Red;
                            isSelect = false;
                            ClearMark();
                        }
                        else
                        {
                            if (isSelect == false && piece.isRed == Chessboard.CurrectCamp) 
                            {
                                piece.BorderColor = Colors.Blue;
                                SelectPiece = piece;
                                isSelect = true;  
                                AddNextMark(piece);
                            }
                        }
                        piece.InvalidateVisual();
                    }
                }
            } 
        }

        //16进制颜色转rgb
        private Color ConvertColor(string colorText)
        {
            string val = colorText;
            val = val.Replace("#", "");

            byte a = System.Convert.ToByte("ff", 16);
            byte pos = 0;
            if (val.Length == 8)
            {
                a = System.Convert.ToByte(val.Substring(pos, 2), 16);
                pos = 2;
            }

            byte r = System.Convert.ToByte(val.Substring(pos, 2), 16);
            pos += 2;

            byte g = System.Convert.ToByte(val.Substring(pos, 2), 16);
            pos += 2;

            byte b = System.Convert.ToByte(val.Substring(pos, 2), 16);

            Color col = Color.FromArgb(a, r, g, b);
            return col;
        }

        /// <summary>
        /// 添加下一步提示标记
        /// </summary>
        /// <param name="piece"></param>
        private void AddNextMark(Piece piece)
        {
            ClearMark();
            List<Point> list = piece.rule.getNextPos(piece, Chessboard.PieceList);
            foreach (Point point in list)
            {
                Ellipse ellipse = new Ellipse();
                ellipse.Tag = 1;
                ellipse.Width = 15;
                ellipse.Height = 15;
                RadialGradientBrush fillBrush = new RadialGradientBrush();
                fillBrush.GradientStops.Add(new GradientStop(ConvertColor("#FFFF4F00"), 0.3));
                fillBrush.GradientStops.Add(new GradientStop(ConvertColor("#93D4842E"), 0.574));
                fillBrush.GradientStops.Add(new GradientStop(ConvertColor("#C2F5F4EC"), 0.8));
                ellipse.Fill = fillBrush;
                ellipse.Stroke = null;

                //point.Offset(-ellipse.Width / 2.0, -ellipse.Height / 2.0);
                Thickness thk = new Thickness();
                thk.Left = point.X * vgap - 8;
                thk.Top = point.Y * hgap - 8;
                ellipse.Margin = thk;
                chessboard.Children.Add(ellipse);
            }
        }

        /// <summary>
        /// 删除标记
        /// </summary>
        private void ClearMark()
        {
            for (int i = 0; i < chessboard.Children.Count; i++)
            {
                if (chessboard.Children[i] is Ellipse)
                { 
                    chessboard.Children.RemoveAt(i);
                    i--; 
                }
            }
        }
    }
}
